package com.fjw.car_send;

import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class TouchPad extends TouchPadBase {

    private int mSplitX;
    private int mWidth;
    private int mHeight;
    private int mAudioIconSize = 150;
    RectF mAudioRectF;
    private int mTurnRoundIconSize = 150;
    RectF mTurnRoundRectF;

    private int mLEDIconSize = 150;
    RectF mLEDRectF;

    private TouchPoint mUPDownPoint = new TouchPoint();
    private TouchPoint mLeftRightPoint = new TouchPoint();
    private TouchPoint mAudioPoint = new TouchPoint();
    RectF mUPRectF;
    RectF mDownRectF;
    RectF mLeftRectF;
    RectF mRightRectF;

    private int mStartBeepIndex = 0;

    final String LOG_TAG = "car_send_touchpad";

    enum ArrowType {
        UP,
        DOWN,
        LEFT,
        RIGHT,
    }

    public TouchPad(Context context) {
        super(context);
    }

    public TouchPad(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public TouchPad(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public TouchPad(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        super.surfaceCreated(holder);
        Canvas canvas;
        canvas = holder.lockCanvas();
        mWidth = canvas.getWidth();
        mHeight = canvas.getHeight();
        mSplitX = mWidth / 3;
        mUPRectF = new RectF(0, 0, mSplitX, mHeight / 2 - mHeight * 0.1f);
        mDownRectF = new RectF(0, mHeight / 2 + mHeight * 0.1f, mSplitX, mHeight);
        mLeftRectF = new RectF(mSplitX, 0, mSplitX + (mWidth - mSplitX) / 2.0f - mWidth * 0.1f, mHeight);
        mRightRectF = new RectF(mSplitX + (mWidth - mSplitX) / 2.0f + mWidth * 0.1f, 0, mWidth, mHeight);
        mUPDownPoint.setScreen(mWidth, mHeight, mUPRectF, mDownRectF);
        mLeftRightPoint.setScreen(mWidth, mHeight, mRightRectF, mLeftRectF);
        mAudioPoint.setScreen(mWidth, mHeight, null, null);
        float yi = (float) mHeight / 4;
        float y = yi;
        mLEDRectF = new RectF((float) mSplitX - (float) (float) mLEDIconSize / 2,
                y - mLEDIconSize / 2,
                mSplitX + (float) mLEDIconSize / 2,
                y + ((float) mLEDIconSize / 2));
        y += yi;
        mAudioRectF = new RectF((float) mSplitX - (float) mAudioIconSize / 2, y - (float) mAudioIconSize / 2,
                mSplitX + (float) mAudioIconSize / 2,
                y + (float) mAudioIconSize / 2);
        y += yi;
        mTurnRoundRectF = new RectF((float) mSplitX - (float) (float) mTurnRoundIconSize / 2,
                y - mTurnRoundIconSize / 2,
                mSplitX + (float) mTurnRoundIconSize / 2,
                y + ((float) mTurnRoundIconSize / 2));
        holder.unlockCanvasAndPost(canvas);

    }

    @Override
    protected void doDraw(Canvas canvas) {
        // 在这里进行绘制
        if (canvas == null) {
            return;
        }
        canvas.drawColor(Color.WHITE);
        int width = canvas.getWidth();
        int height = canvas.getHeight();

        mPaint.setColor(Color.GRAY);
        canvas.drawLine(width / 3, 60, width / 3, height, mPaint);
        if (mFBLevel >= 0) {
            drawArrow(canvas, ArrowType.UP, mFBLevel);
        } else {
            drawArrow(canvas, ArrowType.DOWN, -mFBLevel);
        }
        if (mLRLevel >= 0) {
            drawArrow(canvas, ArrowType.RIGHT, mLRLevel);
        } else {
            drawArrow(canvas, ArrowType.LEFT, -mLRLevel);
        }
        if (MainActivity.getInstance().getmBluetoothGatt() == null) {
            drawDectecting(canvas);
        } else {
            drawSignal(canvas);
        }
        drawAudio(canvas);
        drawTurnRound(canvas);
        drawLED(canvas);
        // drawTestRect(canvas);

    }

    private void drawArrow(Canvas canvas, ArrowType type, int level) {
        Drawable drawable;
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        long currentTime = System.currentTimeMillis();
        switch (level) {
            case 0:
                drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down);
                break;
            case 1:
                if (type == ArrowType.UP || type == ArrowType.DOWN) {
                    int index = (int) (currentTime / 500 % 5 + 1);
                    switch (index) {
                        case 1:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1_f1);
                            break;
                        case 2:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1_f2);
                            break;
                        case 3:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1_f3);
                            break;
                        case 4:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1_f4);
                            break;
                        case 5:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1_f5);
                            break;
                        default:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1);
                    }
                } else {
                    int index = (int) (currentTime / 500 % 2);
                    switch (index) {
                        case 0:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down);
                            break;
                        case 1:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1);
                            break;
                        default:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1);
                    }

                }
                break;
            case 2:
                if (type == ArrowType.UP || type == ArrowType.DOWN) {
                    int index = (int) (currentTime / 300 % 5 + 1);
                    switch (index) {
                        case 1:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up2_f1);
                            break;
                        case 2:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up2_f2);
                            break;
                        case 3:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up2_f3);
                            break;
                        case 4:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up2_f4);
                            break;
                        case 5:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up2_f5);
                            break;
                        default:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1);
                    }
                } else {
                    int index = (int) (currentTime / 500 % 2);
                    switch (index) {
                        case 0:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down);
                            break;
                        case 1:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up2);
                            break;
                        default:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up2);
                    }

                }
                break;
            case 3:

                if (type == ArrowType.UP || type == ArrowType.DOWN) {
                    int index = (int) (currentTime / 100 % 5 + 1);
                    switch (index) {
                        case 1:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up3_f1);
                            break;
                        case 2:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up3_f2);
                            break;
                        case 3:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up3_f3);
                            break;
                        case 4:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up3_f4);
                            break;
                        case 5:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up3_f5);
                            break;
                        default:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up1);
                    }
                } else {
                    int index = (int) (currentTime / 500 % 2);
                    switch (index) {
                        case 0:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down);
                            break;
                        case 1:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up3);
                            break;
                        default:
                            drawable = MainActivity.getInstance().getDrawable(R.drawable.up_down_up3);
                    }

                }
                break;
            default:
                return;
        }
        switch (type) {
            case UP:
                drawable.setBounds(0, 0, width / 3, height);
                drawable.draw(canvas);
                break;
            case DOWN:
                canvas.save();
                canvas.rotate(180, 0, 0);
                canvas.translate(-width, -height);
                drawable.setBounds(width - width / 3, 0, width, height);
                drawable.draw(canvas);
                canvas.restore();
                break;
            case RIGHT:
                canvas.save();
                canvas.rotate(90, 0, 0);
                canvas.translate(0, -width);
                drawable.setBounds(0, 0, height, width - width / 3);
                drawable.draw(canvas);
                canvas.restore();
                break;
            case LEFT:
                canvas.save();
                canvas.rotate(270, 0, 0);
                canvas.translate(-height, 0);
                drawable.setBounds(0, width / 3, height, width);
                drawable.draw(canvas);
                canvas.restore();
                break;
        }
    }

    private void drawDectecting(Canvas canvas) {

        int screenWidth = canvas.getWidth();
        int screenHeight = canvas.getHeight();
        int size = 60;
        Drawable drawable = MainActivity.getInstance().getDrawable(R.drawable.detect);

        drawable.setBounds(screenWidth / 3 - size / 2, 0, screenWidth / 3 + size / 2, size);
        int centerX = screenWidth / 3;
        int centerY = size / 2;
        long current = System.currentTimeMillis();
        canvas.save();
        canvas.rotate((current / 3) % 360, centerX, centerY);
        drawable.draw(canvas);
        canvas.restore();
    }

    private void drawSignal(Canvas canvas) {
        int screenWidth = canvas.getWidth();
        int screenHeight = canvas.getHeight();
        int size = 60;
        Drawable drawable;
        switch (MainActivity.getInstance().getmSignlLevel()) {
            case 0:
                drawable = MainActivity.getInstance().getDrawable(R.drawable.signal0);
                break;
            case 1:
                drawable = MainActivity.getInstance().getDrawable(R.drawable.signal1);
                break;
            case 2:
                drawable = MainActivity.getInstance().getDrawable(R.drawable.signal2);
                break;
            case 3:
                drawable = MainActivity.getInstance().getDrawable(R.drawable.signal3);
                break;
            default:
                return;

        }
        drawable.setBounds(screenWidth / 3 - size / 2, 0, screenWidth / 3 + size / 2, size);
        drawable.draw(canvas);

    }

    private void drawAudio(Canvas canvas) {
        long currentTime = System.currentTimeMillis();

        // 定义一个RectF对象来存储矩形的边界
        Rect rect = new Rect();
        mAudioRectF.round(rect);
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(rect, mPaint);

        Drawable drawable;
        int[] drawables = new int[] {
                R.drawable.audio_down_1,
                R.drawable.audio_down_2,
                R.drawable.audio_down_3
        };
        if (mAudioPoint.isTouched()) {
            drawable = MainActivity.getInstance().getDrawable(drawables[(int) (currentTime / 300 % 3)]);
        } else {
            drawable = MainActivity.getInstance().getDrawable(R.drawable.audio);
        }
        drawable.setBounds(rect);
        drawable.draw(canvas);

        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setTextSize(40);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.WHITE);
        mPaint.setTextAlign(Paint.Align.RIGHT);

        canvas.drawText(Integer.toString(mLastBeep + 1), rect.left + rect.width() / 2,
                rect.top + rect.height() / 2 + 10,
                mPaint);
    }

    private void drawTurnRound(Canvas canvas) {

        Rect rect = new Rect();
        mTurnRoundRectF.round(rect);

        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(rect, mPaint);
        Drawable drawable;
        if (ismTurnRounding()) {
            drawable = MainActivity.getInstance().getDrawable(R.drawable.turn_round_down);
        } else {
            drawable = MainActivity.getInstance().getDrawable(R.drawable.turn_round);
        }
        drawable.setBounds(rect);
        drawable.draw(canvas);
    }

    private void drawLED(Canvas canvas) {

        Rect rect = new Rect();
        mLEDRectF.round(rect);

        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(rect, mPaint);
        Drawable drawable;
        if (mLed > 0) {
            drawable = MainActivity.getInstance().getDrawable(R.drawable.led_down);
        } else {
            drawable = MainActivity.getInstance().getDrawable(R.drawable.led);
        }
        drawable.setBounds(rect);
        drawable.draw(canvas);
    }

    private void drawTestRect(Canvas canvas) {

        Rect rect = new Rect();

        mUPRectF.round(rect);
        mPaint.setColor(Color.GRAY);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(rect, mPaint);

        mDownRectF.round(rect);
        mPaint.setColor(Color.GRAY);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(rect, mPaint);

        mLeftRectF.round(rect);
        mPaint.setColor(Color.GRAY);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(rect, mPaint);

        mRightRectF.round(rect);
        mPaint.setColor(Color.GRAY);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(rect, mPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getActionMasked();
        final int pointerCount = event.getPointerCount();
        if (pointerCount >= 4) {
            MainActivity.getInstance().setActivityIndex(1);
        }

        for (int i = 0; i < pointerCount; i++) {
            int id = event.getPointerId(i);
            float x = event.getX(i);
            float y = event.getY(i);
            if (action == MotionEvent.ACTION_DOWN ||
                    (action == MotionEvent.ACTION_POINTER_DOWN &&
                            i == event.getActionIndex())) {
                if (ismTurnRounding()) {
                    return true;
                }
                if (mAudioRectF.contains(x, y)) {
                    mAudioPoint.setTouched(id, x, y);
                    mStartBeepIndex = mLastBeep;
                    mBeep = mLastBeep + 1;
                } else if (mLEDRectF.contains(x, y)) {
                    if (mLed > 0) {
                        mLed = 0;
                    } else {
                        mLed = 1;
                    }
                    mLedEventID = id;
                } else if (mTurnRoundRectF.contains(x, y)) {
                    startTurnRound();
                    return true;
                } else if (x > 0 && x < mSplitX) {
                    mUPDownPoint.setTouched(id, x, y);
                    mFBLevel = 0;
                } else if (x > mSplitX && x < mWidth) {
                    mLeftRightPoint.setTouched(id, x, y);
                    mLRLevel = 0;
                }
                sendData();
                Log.d(LOG_TAG, "DOWN");
            } else if (action == MotionEvent.ACTION_MOVE) {
                if (ismTurnRounding()) {
                    return true;
                }
                if (id == mAudioPoint.getId() && mAudioPoint.isTouched()) {
                    mAudioPoint.move(x, y);
                    mLastBeep = mStartBeepIndex + mAudioPoint.getLevelY();
                    while (mLastBeep < 0) {
                        mLastBeep += MAX_BEEP_INDEX;
                    }
                    mLastBeep = mLastBeep % MAX_BEEP_INDEX;
                    mBeep = mLastBeep + 1;
                } else if (id == mUPDownPoint.getId() && mUPDownPoint.isTouched()) {
                    mUPDownPoint.move(x, y);
                    mFBLevel = mUPDownPoint.getLevelY();
                } else if (id == mLeftRightPoint.getId() && mLeftRightPoint.isTouched()) {
                    mLeftRightPoint.move(x, y);
                    mLRLevel = mLeftRightPoint.getLevelX();
                }
                sendData();
                Log.d(LOG_TAG, "MOVE");
            } else if (action == MotionEvent.ACTION_UP
                    || (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())
                    || action == MotionEvent.ACTION_CANCEL) {
                if (id == mAudioPoint.getId() && mAudioPoint.isTouched()) {
                    mAudioPoint.release();
                    mBeep = 0;
                } else if (ismTurnRounding()) {
                    stopTurnRound();
                    mFBLevel = 0;
                    mLRLevel = 0;
                } else if (id == mUPDownPoint.getId() && mUPDownPoint.isTouched()) {
                    mUPDownPoint.release();
                    mFBLevel = 0;
                    Log.d(LOG_TAG, "UP 001");
                } else if (id == mLeftRightPoint.getId() && mLeftRightPoint.isTouched()) {
                    mLeftRightPoint.release();
                    mLRLevel = 0;
                    Log.d(LOG_TAG, "UP 002");
                }
                sendData();
                Log.d(LOG_TAG, "UP");
            }
            Log.d(LOG_TAG, "x = " + x + ", y = " + y + ", id = " + id + ", action = " + action);
        }

        // invalidate();
        return true;
    }
}
